home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / splitter.lzh / SPLITTER.C < prev    next >
C/C++ Source or Header  |  1994-02-20  |  11KB  |  430 lines

  1. /*============================================================
  2. **
  3. **    SPLITTER
  4. **
  5. **    Copyright (c)1994 Stuart Coates & Mark Matts
  6. **
  7. **============================================================
  8. **
  9. **    Portable ANSI C version.
  10. **
  11. **
  12. **    Successfully compiled without change on:
  13. **
  14. **        Atari ST - Lattice C 5.60
  15. **        Atari ST - GNU C 2.4.5
  16. **        MSDOS 6.20 - GNU C (32 Bit)
  17. **        OS/2 2.1 - GNU C
  18. **        Sequent Dynix/PTX 2.10
  19. **        IBM RS/6000 AIX 3.2.0
  20. **
  21. **
  22. **    Porting issues:
  23. **
  24. **        Source code is ANSI therefore K&R compilers
  25. **        will require the function definitions to be
  26. **        modified to comply with K&R style.
  27. **
  28. **        Compiler settings should be modified so that:
  29. **
  30. **            short int = 16 bits
  31. **            long int  = 32 bits
  32. **
  33. **
  34. **============================================================
  35. **
  36. **    Version 2.00
  37. **
  38. **    94/02/19 SINC    Initial release.
  39. **
  40. **
  41. **
  42. */
  43.  
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <sys/file.h>
  48. #include <sys/types.h>
  49. #include <sys/stat.h>
  50.  
  51. #define SPLITTER_VERSION    "2.00"
  52. #define    BUFFER_SIZE        102400
  53. #define EXIT_OK            0
  54. #define EXIT_INVALID_ARGS    1
  55. #define    EXIT_INVALID_INFILE    2
  56. #define EXIT_INVALID_INLENGTH    3
  57. #define    EXIT_MEMORY_ALLOC_ERR    4
  58. #define EXIT_FILE_CREATE    5
  59. #define EXIT_INVALID_CHECK    6
  60. #define EXIT_FILE_READ        7
  61. #define EXIT_INFO_READ        8
  62. #define EXIT_FILE_WRITE        9
  63. #define EXIT_TOO_MANY_FILES    10
  64.  
  65. /* ANSI Prototypes */
  66. int main(int argc, char **argv);
  67. void logo_show(void);
  68. void usage_show(void);
  69. int unsplit_files(char *input_file_prefix,short write_flag);
  70. int split_files(char *input_file,char *output_files_prefix,long max_filesize);
  71. void input_file_error(char *input_file);
  72. void input_file_zero_error(char *input_file);
  73. void memory_allocation_error(void);
  74. void make_filename(char *buffer,char *prefix,short number);
  75. long calc_check_value(unsigned long start_value,char *buffer,long length);
  76. void file_write_error(char *file);
  77. void null_term_line(char *string);
  78. void validation_failed(void);
  79. void too_many_files(void);
  80. char *check_value_padout(unsigned long check_value, char *check_value_string);
  81.  
  82. int main(int argc, char **argv)
  83. {
  84.     logo_show();
  85.     if(argc!=4 && argc!=3)    {
  86.         usage_show();
  87.         return(EXIT_INVALID_ARGS);
  88.         }
  89.     if(argc==3 && strcmp(argv[1],"-u")!=0 && strcmp(argv[1],"-c")!=0)    {
  90.         usage_show();
  91.         return(EXIT_INVALID_ARGS);
  92.         }
  93.     if(strcmp(argv[1],"-u")==0)
  94.         return(unsplit_files(argv[2],1));
  95.     else
  96.     if(strcmp(argv[1],"-c")==0)
  97.         return(unsplit_files(argv[2],0));
  98.     else
  99.         return(split_files(argv[1],argv[2],strtol(argv[3],NULL,10)));
  100. }
  101.  
  102. int unsplit_files(char *input_file_prefix,short write_flag)
  103. {
  104.     FILE *fpin;
  105.     FILE *fpout;
  106.     FILE *fpinfo;
  107.     char *buffer;
  108.     char *info_filename;
  109.     char *input_filename;
  110.     short block_number=1;
  111.     char *output_filename;
  112.     char *workspace;
  113.     long expand_filesize;
  114.     long block_size;
  115.     unsigned long stored_check_value;
  116.     unsigned long file_check_value;
  117.     long bytes_read;
  118.     long error;
  119.     char check_value_string[9];
  120.     
  121.     info_filename=malloc(strlen(input_file_prefix)+(5*sizeof(char)));
  122.     if(info_filename==NULL)    {
  123.         memory_allocation_error();
  124.         return(EXIT_MEMORY_ALLOC_ERR);
  125.         }
  126.     output_filename=malloc(1024);
  127.     if(output_filename==NULL)    {
  128.         memory_allocation_error();
  129.         return(EXIT_MEMORY_ALLOC_ERR);
  130.         }
  131.     workspace=malloc(1024);
  132.     if(workspace==NULL)    {
  133.         memory_allocation_error();
  134.         return(EXIT_MEMORY_ALLOC_ERR);
  135.         }
  136.     input_filename=malloc(strlen(input_file_prefix)+(5*sizeof(char)));
  137.     if(input_filename==NULL)    {
  138.         memory_allocation_error();
  139.         return(EXIT_MEMORY_ALLOC_ERR);
  140.         }
  141.     buffer=malloc(BUFFER_SIZE);
  142.     if(buffer==NULL)    {
  143.         memory_allocation_error();
  144.         return(EXIT_MEMORY_ALLOC_ERR);
  145.         }
  146.     make_filename(info_filename,input_file_prefix,0);
  147.     fpinfo=fopen(info_filename,"r");
  148.     if(fpinfo==NULL)    {
  149.         input_file_error(info_filename);
  150.         return(EXIT_INFO_READ);
  151.         }
  152.     fgets(workspace,1024,fpinfo);
  153.     null_term_line(workspace);
  154.     printf("Files created using: %s\n",workspace);
  155.     fgets(workspace,1024,fpinfo);
  156.     null_term_line(workspace);
  157.     strcpy(output_filename,workspace);
  158.     if(write_flag==1)
  159.         printf("Recreating file    : %s",output_filename);
  160.     else
  161.         printf("Original filename  : %s",output_filename);
  162.     fgets(workspace,1024,fpinfo);
  163.     null_term_line(workspace);
  164.     expand_filesize=strtol(workspace,NULL,10);
  165.     printf(" %ld Bytes.\n",expand_filesize);
  166.     
  167.     if(write_flag==1)    {
  168.         fpout=fopen(output_filename,"wb");
  169.         if(fpout==NULL)    {
  170.             file_write_error(output_filename);
  171.             return(EXIT_FILE_CREATE);
  172.             }
  173.         }
  174.     for(;;)    {
  175.         fgets(workspace,1024,fpinfo);
  176.         if(feof(fpinfo))
  177.             break;
  178.         null_term_line(workspace);
  179.         block_size=strtol(workspace,NULL,10);
  180.         fgets(workspace,1024,fpinfo);
  181.         null_term_line(workspace);
  182.         stored_check_value=strtoul(workspace,NULL,16);
  183.         make_filename(input_filename,input_file_prefix,block_number);
  184.         fpin=fopen(input_filename,"rb");
  185.         if(fpin==NULL)    {
  186.             input_file_error(input_filename);
  187.             return(EXIT_INFO_READ);
  188.             }
  189.         bytes_read=0;
  190.         file_check_value=0;
  191.         printf("\nReading file: %s  Check:%s",input_filename,check_value_padout(stored_check_value,check_value_string));
  192.         for(;;)    {
  193.             bytes_read=fread(buffer,1,BUFFER_SIZE,fpin);
  194.             if(write_flag==1)    {
  195.                 error=fwrite(buffer,1,bytes_read,fpout);
  196.                 if(error!=bytes_read)    {
  197.                     file_write_error(output_filename);
  198.                     return(EXIT_FILE_WRITE);
  199.                     }
  200.                 }
  201.             file_check_value=calc_check_value(file_check_value,buffer,bytes_read);
  202.             if(feof(fpin))
  203.                 break;
  204.             }
  205.         fclose(fpin);
  206.         printf("/%s",check_value_padout(file_check_value,check_value_string));
  207.         if(file_check_value != stored_check_value)    {
  208.             validation_failed();
  209.             return(EXIT_INVALID_CHECK);
  210.             }
  211.         else    {
  212.             printf(" - OK");
  213.             }
  214.         block_number++;
  215.         }
  216.     fclose(fpinfo);
  217.     if(write_flag==1)
  218.         fclose(fpout);
  219.     printf("\n\nFinished.\n\n");
  220.     free(buffer);
  221.     free(workspace);
  222.     free(info_filename);
  223.     free(input_filename);
  224.     free(output_filename);
  225.     return(0);
  226. }
  227.  
  228.  
  229. int split_files(char *input_file,char *output_files_prefix,long max_filesize)
  230. {
  231.     FILE *fpin;
  232.     FILE *fpout;
  233.     FILE *fpinfo;
  234.     struct stat fileinfo;
  235.     char *output_filename;
  236.     char *info_filename;
  237.     char *buffer;
  238.     long input_bytes_left;
  239.     long bytes_in_current_block=0;
  240.     long bytes_read=0;
  241.     short block_number=1;
  242.     unsigned long file_check_value;
  243.     long error;
  244.     char check_value_string[9];
  245.  
  246.     if(stat(input_file,&fileinfo)!=0)    {
  247.         input_file_error(input_file);
  248.         return(EXIT_INVALID_INFILE);
  249.         }
  250.     if(fileinfo.st_size==0)    {
  251.         input_file_zero_error(input_file);
  252.         return(EXIT_INVALID_INLENGTH);
  253.         }
  254.     input_bytes_left=fileinfo.st_size;
  255.     
  256.     
  257.     if((input_bytes_left / max_filesize) > 999)    {
  258.         too_many_files();
  259.         return(EXIT_TOO_MANY_FILES);
  260.         }
  261.     
  262.     
  263.     output_filename=malloc(strlen(output_files_prefix)+(5*sizeof(char)));
  264.     if(output_filename==NULL)    {
  265.         memory_allocation_error();
  266.         return(EXIT_MEMORY_ALLOC_ERR);
  267.         }
  268.     info_filename=malloc(strlen(output_files_prefix)+(5*sizeof(char)));
  269.     if(info_filename==NULL)    {
  270.         memory_allocation_error();
  271.         return(EXIT_MEMORY_ALLOC_ERR);
  272.         }
  273.     buffer=malloc(BUFFER_SIZE);
  274.     if(buffer==NULL)    {
  275.         memory_allocation_error();
  276.         return(EXIT_MEMORY_ALLOC_ERR);
  277.         }
  278.     make_filename(info_filename,output_files_prefix,0);
  279.     fpin=fopen(input_file,"rb");
  280.     if(fpin==NULL)    {
  281.         input_file_error(input_file);
  282.         return(EXIT_INVALID_INFILE);
  283.         }
  284.     fpinfo=fopen(info_filename,"w");
  285.     if(fpinfo==NULL)    {
  286.         file_write_error(info_filename);
  287.         return(EXIT_FILE_CREATE);
  288.         }
  289.     fprintf(fpinfo,"SPLITTER "SPLITTER_VERSION"\n%s\n%ld\n",input_file,fileinfo.st_size);
  290.     printf("Splitting file: %s into ",input_file);
  291.     if((max_filesize*(input_bytes_left/max_filesize)) == input_bytes_left)
  292.         printf("%d",(int)(input_bytes_left/max_filesize));
  293.     else
  294.         printf("%d",(int)((input_bytes_left/max_filesize)+1));
  295.     printf(" parts.\n");
  296.     for(;;)    {
  297.         make_filename(output_filename,output_files_prefix,block_number);
  298.         fpout=fopen(output_filename,"wb");
  299.         if(fpout==NULL)    {
  300.             file_write_error(output_filename);
  301.             return(EXIT_FILE_CREATE);
  302.             }
  303.         bytes_in_current_block=0;
  304.         file_check_value=0;
  305.         printf("\nCreating file: %s",output_filename);
  306.